home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Demos / Extend 3.0 Demo / Demo Libraries / Demo Engineering Lib / Demo Engineering Lib.rsrc / MODL_6618_Phase Locked Loop < prev    next >
Encoding:
Text File  |  1994-06-22  |  8.8 KB  |  502 lines

  1. real    twoPi, dt2, normal, b0, b1, a0, a1, int1, int0;
  2. real    loFreq, hiFreq, x, p, z;
  3. integer    phOut, divOut, oldState, oldVCOstate, oldSq, phPulse;
  4. integer    numClks;
  5.  
  6.  
  7. procedure
  8. pllCirc();
  9.  
  10. integer
  11. pllComp(integer change);
  12.  
  13. integer
  14. checkPLL()
  15. {
  16. twoPi = 2.0*PI;
  17. ** first check data 
  18. if (novalue(bandwidth+damp+divider+vcolow+vcohi))
  19.     return(1);
  20. if (bandwidth <= 0.0 || divider < 1.0 || divider > 1000000000.0
  21.         || damp < 0.1 || VCOLow < 0.0 || VCOHi < 0.0)
  22.     return(1);
  23. if (pllComp(FALSE))
  24.     return(2);
  25. return(FALSE);
  26. }
  27.  
  28.  
  29. ** This message occurs for each step in the simulation.
  30. on simulate
  31. {
  32. pllCirc();
  33.  
  34. ** sysGlobal2 is the file reference number for the DEBUG TRACE
  35. if( sysGlobal2 != 0.0 )    ** 0 is error, check for open file for TRACE
  36.     {
  37. // template for report:      |BLOCK NAME *****************|block number |BLOCK NUMBER*******
  38.     fileWrite(sysGlobal2,"Phase Locked Loop                  block number "+(MyBlockNumber())+".  Current Time:"+currentTime+".","",True);
  39.     if(getBlockLabel(myBlockNumber()) != "")
  40.         fileWrite(sysGlobal2,"Block Label: "+getBlockLabel(myBlockNumber()),"",True);
  41.     fileWrite(sysGlobal2,"     In = "+InputIn,"",True);
  42.     fileWrite(sysGlobal2,"     Freq Out = "+FreqOut,"",True);
  43.     fileWrite(sysGlobal2,"     Demod Out = "+DemodOut,"",True);
  44.     fileWrite(sysGlobal2,"     Phase Out = "+PhaseOut,"",True);
  45.     fileWrite(sysGlobal2," ","",True);
  46.     }
  47. }
  48.  
  49. on endSim
  50. {
  51. ** sysGlobal1 is the file reference number for the TEXT REPORT
  52. if( sysGlobal1 != 0.0 ) ** 0 is error, check for open file for REPORT
  53.     {
  54. // template for report:      |BLOCK NAME *****************|block number |BLOCK NUMBER*******
  55.     fileWrite(sysGlobal1,"Phase Locked Loop                  block number "+(MyBlockNumber()),"",True);
  56.     if(getBlockLabel(myBlockNumber()) != "")
  57.         fileWrite(sysGlobal1,"Block Label: "+getBlockLabel(myBlockNumber()),"",True);
  58.     fileWrite(sysGlobal1,"     Bandwidth = "+bandwidth,"",True);
  59.     fileWrite(sysGlobal1,"     Damping = "+damp,"",True);
  60.     fileWrite(sysGlobal1,"     Frequency Multiplier = "+Divider,"",True);
  61.     fileWrite(sysGlobal1,"     VCO Low Limit = "+VCOLow,"",True);
  62.     fileWrite(sysGlobal1,"     VCO High Limit = "+VCOHi,"",True);
  63.     if (passive)
  64.         fileWrite(sysGlobal1,"     Passive loop filter","",True);
  65.     else
  66.         fileWrite(sysGlobal1,"     Active loop filter","",True);
  67.     if (exor)
  68.         fileWrite(sysGlobal1,"     Exclusive-Or detector","",True);
  69.     else if (Tri)
  70.         fileWrite(sysGlobal1,"     Frequency Tri-State","",True);
  71.     else
  72.         fileWrite(sysGlobal1,"     RS Flip Flop","",True);
  73.     if( comments != "" )
  74.         fileWrite(sysGlobal1,"     Comments = "+comments,"",True);        
  75.     fileWrite(sysGlobal1," ","",True);
  76.     }
  77. }
  78.  
  79. Procedure
  80. ErrorCheck()
  81. {
  82. integer    ret;
  83.  
  84. ret = checkPLL();
  85.  
  86. if (ret == 1)
  87.     {
  88.     usererror("Please enter all parameters as positive values in Phase \
  89. Locked Loop block "+myBlockNumber());
  90.     abort;
  91.     }
  92. else if (ret == 2)
  93.     {
  94.     usererror("The damping value was too low... changed to 1.1*minimum \
  95. damping for this configuration in Phase Locked Loop block "
  96.                                                 +myBlockNumber());
  97.     abort;
  98.     }
  99. }
  100.  
  101. ** If the dialog data is inconsistent for simulation, abort.
  102. on OK
  103. {
  104. ErrorCheck();
  105. }
  106.  
  107.  
  108. ** If the dialog data is inconsistent for simulation, abort.
  109. on checkdata
  110. {
  111. ErrorCheck();
  112. }
  113.  
  114. on stepSize
  115. {
  116. real    temp;
  117.  
  118. twoPi = 2.0*PI;
  119. temp = min2(twoPi/20.0*max2(p,z/4.0), 1.0/(hiFreq*20.0));
  120. if (deltaTime > temp)
  121.     deltaTime = temp;
  122. }
  123.  
  124. ** Initialize any simulation variables.
  125. on initsim
  126. {
  127. twoPi = 2.0*PI;
  128. if (pllComp(FALSE))
  129.     abort;
  130. }
  131.  
  132.  
  133. on createBlock
  134. {
  135. divider = 1.0;
  136. }
  137.  
  138. integer
  139. pllComp(integer change)
  140. {
  141. integer        j;
  142. real        temp, pole, zero, w, kv, kd;
  143. real        minDamp, t1, t2;
  144. integer        longD;
  145.  
  146. dt2 = deltaTime/2.0;
  147.  
  148. divider = int(divider);
  149. loFreq = VCOLow;
  150. hiFreq = VCOHi;
  151.  
  152. if (loFreq > hiFreq)
  153.     {
  154.     temp = loFreq;
  155.     loFreq = hiFreq;
  156.     hiFreq = temp;
  157.     }
  158.  
  159. w = twoPi*bandwidth;
  160.  
  161. ** first, calculate pole, zero from band, damping, vco, divider 
  162. ** calc Kv 
  163. if (exor)            ** EXOR 
  164.     kd = 1.0/pi;
  165. else if (tri)    ** phase/frequency 
  166.     kd = 0.5/twoPi;
  167. else                                ** flip flop 
  168.     kd = 1.0/twoPi;
  169.     
  170. kv = kd*twoPi*(hiFreq-loFreq)/divider;
  171.  
  172. if (passive)    ** passive 
  173.     {
  174.     minDamp = w/(2.0*kv);
  175.     if (damp < minDamp)
  176.         {
  177.         damp = minDamp*1.1;
  178.         return(TRUE);
  179.         }
  180.     t1 = kv/(w*w);
  181.     t2 = 2.0*damp/w-1.0/kv;
  182.     p = 1.0/t1;
  183.     z = 1.0/t2;
  184.     ** then, warp for simulation 
  185.     p = (1.0-exp(-p*dt2))/dt2;
  186.     z = (1.0-exp(-z*dt2))/dt2;
  187.     normal = p/z;
  188.     b0 = 1.0;
  189.     b1 = p;
  190.     a0 = 1.0;
  191.     a1 = z;
  192.     }
  193. else     ** active 
  194.     {
  195.     minDamp = 0;
  196.     t1 = kv/(w*w);
  197.     t2 = 2.0*damp/w;
  198.     p = 1.0/t1;
  199.     z = 1.0/t2;
  200.     normal = p;
  201.     a0 = t2/t1;
  202.     }
  203.  
  204. numClks = 0;
  205. x = 0.0;
  206. phOut = 0;
  207. divOut = 0;
  208. oldState = 0;
  209. oldVCOstate = 0;
  210. oldSq = 0;
  211. phPulse = 0;
  212. int0 = 0.0;
  213. int1 = 0.0;
  214. return(FALSE);
  215. }
  216.  
  217.  
  218. procedure
  219. pllCirc()
  220. {
  221. real        eo, demod, p;
  222. integer        sq, sigState, vcoState, state, i, pState;
  223.  
  224. sigState = inputIn > 0.5;
  225.  
  226. for (i=0; i<2; i++)
  227.     {
  228.     vcoState = divOut;
  229.     
  230.     ** first, get phase detector output 
  231.     if (exor)    ** exor phase detector 
  232.         {
  233.         pState = FALSE;
  234.         phPulse = TRUE;
  235.         phOut = (sigState != vcoState);    ** exor
  236.         }
  237.     else if (tri)    ** freq tri-state detector 
  238.         {
  239.         pState = TRUE;
  240.         state = oldState;    ** save new state 
  241.         switch (state)    ** last state 
  242.             {
  243.             case 0:
  244.                 if (sigState && vcoState)
  245.                     {
  246.                     state = 6;
  247.                     phPulse = FALSE;
  248.                     }
  249.                 else if (sigState)
  250.                     {
  251.                     state = 5;
  252.                     phPulse = FALSE;
  253.                     }
  254.                 else if (vcoState)
  255.                     {
  256.                     state = 1;
  257.                     phPulse = TRUE;
  258.                     phOut = 0.0;
  259.                     }
  260.                 break;
  261.             case 1:
  262.                 if (sigState)
  263.                     {
  264.                     state = 6;
  265.                     phPulse = FALSE;
  266.                     }
  267.                 else if (! vcoState)
  268.                     {
  269.                     state = 0;
  270.                     phPulse = TRUE;
  271.                     phOut = 0.0;
  272.                     }
  273.                 break;
  274.             case 2:
  275.                 if (! sigState)
  276.                     {
  277.                     state = 1;
  278.                     phPulse = TRUE;
  279.                     phOut = 0.0;
  280.                     }
  281.                 else if (! vcoState)
  282.                     {
  283.                     state = 3;
  284.                     phPulse = TRUE;
  285.                     phOut = 0.0;
  286.                     }
  287.                 break;
  288.             case 3:
  289.                 if (! sigState)
  290.                     {
  291.                     state = 0;
  292.                     phPulse = TRUE;
  293.                     phOut = 0.0;
  294.                     }
  295.                 else if (vcoState)
  296.                     {
  297.                     state = 2;
  298.                     phPulse = TRUE;
  299.                     phOut = 0.0;
  300.                     }
  301.                 break;
  302.             case 4:
  303.                 if (sigState && vcoState)
  304.                     {
  305.                     state = 6;
  306.                     phPulse = FALSE;
  307.                     }
  308.                 else if (sigState)
  309.                     {
  310.                     state = 11;
  311.                     phPulse = TRUE;
  312.                     phOut = 1.0;
  313.                     }
  314.                 else if (vcoState)
  315.                     {
  316.                     state = 1;
  317.                     phPulse = TRUE;
  318.                     phOut = 0.0;
  319.                     }
  320.                 break;
  321.             case 5:
  322.                 if (! sigState)
  323.                     {
  324.                     state = 4;
  325.                     phPulse = FALSE;
  326.                     }
  327.                 else if (vcoState)
  328.                     {
  329.                     state = 2;
  330.                     phPulse = TRUE;
  331.                     phOut = 0.0;
  332.                     }
  333.                 break;
  334.             case 6:
  335.                 if (! sigState)
  336.                     {
  337.                     state = 7;
  338.                     phPulse = FALSE;
  339.                     }
  340.                 else if (! vcoState)
  341.                     {
  342.                     state = 5;
  343.                     phPulse = FALSE;
  344.                     }
  345.                 break;
  346.             case 7:
  347.                 if (sigState)
  348.                     {
  349.                     state = 10;
  350.                     phPulse = TRUE;
  351.                     phOut = 1.0;
  352.                     }
  353.                 else if (! vcoState)
  354.                     {
  355.                     state = 4;
  356.                     phPulse = FALSE;
  357.                     }
  358.                 break;
  359.             case 8:
  360.                 if (sigState && vcoState)
  361.                     {
  362.                     state = 6;
  363.                     phPulse = FALSE;
  364.                     }
  365.                 else if (sigState)
  366.                     {
  367.                     state = 11;
  368.                     phPulse = TRUE;
  369.                     phOut = 1.0;
  370.                     }
  371.                 else if (vcoState)
  372.                     {
  373.                     state = 7;
  374.                     phPulse = FALSE;
  375.                     }
  376.                 break;
  377.             case 9:
  378.                 if (sigState)
  379.                     {
  380.                     state = 10;
  381.                     phPulse = TRUE;
  382.                     phOut = 1.0;
  383.                     }
  384.                 else if (! vcoState)
  385.                     {
  386.                     state = 8;
  387.                     phPulse = TRUE;
  388.                     phOut = 1.0;
  389.                     }
  390.                 break;
  391.             case 10:
  392.                 if (! sigState)
  393.                     {
  394.                     state = 9;
  395.                     phPulse = TRUE;
  396.                     phOut = 1.0;
  397.                     }
  398.                 else if (! vcoState)
  399.                     {
  400.                     state = 11;
  401.                     phPulse = TRUE;
  402.                     phOut = 1.0;
  403.                     }
  404.                 break;
  405.             case 11:
  406.                 if (! sigState)
  407.                     {
  408.                     state = 8;
  409.                     phPulse = TRUE;
  410.                     phOut = 1.0;
  411.                     }
  412.                 else if (vcoState)
  413.                     {
  414.                     state = 6;
  415.                     phPulse = FALSE;
  416.                     }
  417.                 break;
  418.             default:
  419.                 state = 0;
  420.                 phPulse = FALSE;
  421.                 break;
  422.             }
  423.         oldState = state;    ** save new state 
  424.         }
  425.     else    ** rs flip-flop 
  426.         {
  427.         pState = FALSE;
  428.         phPulse = TRUE;
  429.         if (sigState && ! oldState) ** old sigState
  430.             phOut = 1.0;
  431.         else if (vcoState && ! oldVCOstate) ** old vcoState
  432.             phOut = 0.0;
  433.         oldState = sigState;    ** save new state 
  434.         oldVCOstate = vcoState;    ** save new state         
  435.         }
  436.     
  437.     ** then pass thru filter 
  438.     if (passive)    ** passive filter 
  439.         {
  440.         if (phPulse)
  441.             int0 = phOut*normal-int1*b1;
  442.         else
  443.             int0 = 0.0;
  444.         int1 = int1+dt2*int0;
  445.         eo = int0+a1*int1;
  446.         }
  447.     else    ** active filter integrator 
  448.         {
  449.         if (phPulse)
  450.             p = phOut-0.5;
  451.         else
  452.             p = 0.0;
  453.         int1 += dt2*normal*p;
  454.         demod = int1;
  455.     
  456.         if (demod > 1.0)
  457.             demod = 1.0;
  458.         else if (demod < 0.0)
  459.             demod = 0.0;
  460.         int1 = demod;
  461.         eo = a0*p+demod;
  462.         }
  463.     
  464.     ** damping limit 
  465.     if (eo>1.0)
  466.         eo = 1.0;
  467.     else if (eo<0.0)
  468.         eo = 0.0;
  469.     
  470.     ** then get vco output, eo is control  
  471.     x = x+dt2*(loFreq+eo*(hiFreq-loFreq));
  472.     
  473. **if (eo != 0.0)
  474. **    usererror("x="+x+", eo="+eo+", dt2="+dt2+"loFreq="+loFreq+", hiFreq="+hiFreq);
  475.     
  476.     while (x >= 1.0)
  477.         x -= 1.0;
  478.         
  479.     sq = (x>=0.0 && x<0.5);
  480.     
  481.     ** then get divider output 
  482.     if (sq != oldSq)
  483.         {
  484.         numClks++;
  485.         oldSq = sq;    
  486.         }
  487.     if (numClks >= divider)
  488.         {
  489.         divOut = ! divOut;
  490.         numClks = 0;
  491.         }
  492.     }
  493.  
  494. if (pState)
  495.     phaseOut = phPulse;
  496. else
  497.     phaseOut = 0.0;
  498. freqOut = sq;
  499. demodOut = eo;
  500. }
  501.  
  502.